// ===============================================================================
// scan: sequential scan of a large descriptor collection
// Created in September 2007 as a project for an Advanced Database Systems course
// (c) Reykjavik University, Björn Þór Jónsson, Kristleifur Daðason, Herwig Lejsek
// Contact author: Björn Þór Jónsson, Reykjavík University, bjorn@ru.is
// ===============================================================================

#include "DescMapper.h"

DescMapper::DescMapper(string _filename, unsigned int _numDims)
{
	numDims = _numDims;

	file = fopen(_filename.c_str(), "rb");
        if (errno != 0)         {
                cout << "DescMapper (" << _filename << ")" << endl;
                cout << "fopen error: " << errno << ": " << strerror(errno) << endl;
                exit(0);
        }

	struct stat filestat;	
	fstat(fileno(file), &filestat);
	descSize = getFlexDescByteSize(numDims);
	fileSize = filestat.st_size;
	numDescs = fileSize / descSize;

	//mapPtr = (unsigned char *) mmap(0, filestat.st_size, PROT_READ, MAP_SHARED, fileno(file), 0); 
	mapPtr = (unsigned char*) malloc(fileSize);
	fread(mapPtr, fileSize, 1, file);
	if (errno != 0)
	{
		cout << "errno: " << errno << ", message: " << strerror(errno) << endl;
		exit(0);
	}

	// Mark no scan in progress
	currDesc = -1;
}

void DescMapper::open()
{
	currDesc = 0;
}

FlexDescriptor* DescMapper::next()
{
	if (currDesc == numDescs)
		return NULL;

	off_t offset = currDesc++ * descSize;
	return (FlexDescriptor*) (mapPtr + offset);
}

void DescMapper::close()
{
	currDesc = -1;
}

DescMapper::~DescMapper()
{
	if (currDesc > -1)
		close();

	//munmap(mapPtr, fileSize);
	free(mapPtr);
	fclose(file);
}

